package mapkit.layers
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.geom.Point;

	import mapkit.carto.Feature;
	import mapkit.carto.IMap;
	import mapkit.carto.IMapLocator;
	import mapkit.carto.MapLocator;
	import mapkit.carto.Location;

	import mx.core.UIComponent;
	import mx.styles.ISimpleStyleClient;

	[DefaultProperty("feature")]
	public class MapGraphic extends UIComponent
	{
		private var _map:IMap=null;

		public function get map():IMap
		{
			return _map;
		}

		public function set map(value:IMap):void
		{
			_map=value;
		}

		private var _locator:IMapLocator=new MapLocator();

		public function get locator():IMapLocator
		{
			return _locator;
		}

		public function set locator(value:IMapLocator):void
		{
			_locator=value;
		}

		private var _feature:Feature=new Feature();

		public function get feature():Feature
		{
			return _feature;
		}

		[Bindable]
		public function set feature(value:Feature):void
		{
			_feature=value;
		}

		public function get anchor():Point
		{
			return new Point(x, y);
		}

		public function set anchor(value:Point):void
		{
			x=value.x;
			y=value.y;
		}

		public function get where():Location
		{
			return feature.shape.where;
		}

		[Bindable]
		public function set where(value:Location):void
		{
			feature.shape.where=value;
		}

		public function invalidateWhere():void
		{
			callLater(updateWhere);
		}

		public function invalidateAnchor():void
		{
			callLater(updateAnchor);
		}

		protected function updateWhere():void
		{
			if (locator && map)
			{
				where=locator.toMapPoint(anchor, map);
			}
		}

		protected function updateAnchor():void
		{
			if (locator && map)
			{
				anchor=locator.fromMapPoint(where, map);
			}
		}

		private var _skin:DisplayObject=null;

		protected function updateSkin():void
		{
			if (_skin)
			{
				if (contains(_skin))
				{
					removeChild(_skin);
				}
				_skin=null;
			}

			var skinStyle:*=getStyle("skin");
			if (skinStyle is DisplayObject)
			{
				_skin=skinStyle;
				if (_skin is Sprite)
				{
					(_skin as Sprite).mouseEnabled=false;
				}
			}

			if (skinStyle is Class)
			{
				_skin=new skinStyle();
			}

			if (_skin)
			{
				addChild(_skin);
				if (!width || !height)
				{
					width=_skin.width;
					height=_skin.height;
				}
				else
				{
					_skin.width=width;
					_skin.height=height;
				}
				_skin.x=-0.5 * width;
				_skin.y=-0.5 * height;
			}
			else
			{
				graphics.clear();
				graphics.beginFill(0xff0000, 0.6);
				graphics.drawRect(-0.5 * width, -0.5 * height, width, height);
				graphics.endFill();
			}
		}

		override public function styleChanged(styleProp:String):void
		{
			super.styleChanged(styleProp);

			if (_skin is ISimpleStyleClient)
			{
				(_skin as ISimpleStyleClient).styleName=this;
			}
			invalidateDisplayList();
		}

		override protected function createChildren():void
		{
			super.createChildren();
			updateSkin();
		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);

			updateSkin();
			updateAnchor();
		}

	}
}